package cuongnh.project.japanesediary.vocabulary.ui.editor.kanji.page.compound.section;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.databinding.viewers.ObservableSetContentProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import cuongnh.project.japanesediary.vocabulary.application.Activator;
import cuongnh.project.japanesediary.vocabulary.common.CommonServices;
import cuongnh.project.japanesediary.vocabulary.common.CommonUtils;
import cuongnh.project.japanesediary.vocabulary.model.Kanji;
import cuongnh.project.japanesediary.vocabulary.model.Sentence;
import cuongnh.project.japanesediary.vocabulary.model.Vocabulary;
import cuongnh.project.japanesediary.vocabulary.ui.dialog.AddRelatedVocabularyDialog;

public class CompoundWordsSection extends SectionPart {

	private DataBindingContext m_bindingContext;
	private Kanji kanji;
	private CommonServices commonServices;
	private TableViewer tblvCompoundWords;
	private Table tblCompoundWords;
	private Vocabulary selectedWord;
	private Table tblExamples;
	private TableViewer tblvExamples;

	/**
	 * Create the SectionPart.
	 * 
	 * @param parent
	 * @param toolkit
	 * @param style
	 */
	public CompoundWordsSection(Composite parent, FormToolkit toolkit,
			int style, Kanji kanji, CommonServices commonServices) {
		super(parent, toolkit, style);
		this.commonServices = commonServices;
		this.kanji = kanji;
		initData();
		createClient(getSection(), toolkit);
	}

	public void initData() {
		kanji = commonServices.getKanjiDao().getKanjiWithVocabularies(
				kanji.getKanjiId());
	}

	/**
	 * Fill the section.
	 */
	private void createClient(Section section, FormToolkit toolkit) {
		section.setText("Compound Words");
		createToolBar(section);
		Composite container = toolkit.createComposite(section);
		section.setClient(container);
		container.setLayout(new GridLayout(1, false));

		Composite composite = new Composite(container, SWT.NONE);
		GridData gd_composite = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
		gd_composite.widthHint = 543;
		composite.setLayoutData(gd_composite);
		composite.setLayout(new GridLayout(1, false));

		Group grpCompoundWords = new Group(composite, SWT.NONE);
		GridData gd_grpCompoundWords = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
		gd_grpCompoundWords.widthHint = 507;
		grpCompoundWords.setLayoutData(gd_grpCompoundWords);
		grpCompoundWords.setText("Compound Words");
		grpCompoundWords.setLayout(new GridLayout(1, false));
		Composite composite_2 = new Composite(grpCompoundWords, SWT.NONE);
		composite_2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true,
				1, 1));

		tblvCompoundWords = new TableViewer(composite_2, SWT.BORDER
				| SWT.FULL_SELECTION | SWT.MULTI);
		tblCompoundWords = tblvCompoundWords.getTable();
		tblCompoundWords.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
				true, 1, 1));
		tblCompoundWords.setHeaderVisible(true);
		tblCompoundWords.setLinesVisible(true);

		TableViewerColumn tbclvVocabulary = new TableViewerColumn(
				tblvCompoundWords, SWT.NONE);
		TableColumn tblclmnVocabulary = tbclvVocabulary.getColumn();
		tblclmnVocabulary.setText("Vocabulary");

		TableViewerColumn tbclvFurigana = new TableViewerColumn(
				tblvCompoundWords, SWT.NONE);
		TableColumn tblclmnFurigana = tbclvFurigana.getColumn();
		tblclmnFurigana.setText("Furigana");

		TableViewerColumn tbclvHanviet = new TableViewerColumn(
				tblvCompoundWords, SWT.NONE);
		TableColumn tblclmnHanviet = tbclvHanviet.getColumn();
		tblclmnHanviet.setText("HAN-VIET");

		TableViewerColumn tbclvVnMeaning = new TableViewerColumn(
				tblvCompoundWords, SWT.NONE);
		TableColumn tblclmnVietnameseMeaning = tbclvVnMeaning.getColumn();
		tblclmnVietnameseMeaning.setText("Vietnamese meaning");
		TableColumnLayout tblColumnLayout1 = new TableColumnLayout();
		tblColumnLayout1.setColumnData(tblclmnVocabulary, new ColumnWeightData(
				25, true));
		tblColumnLayout1.setColumnData(tblclmnFurigana, new ColumnWeightData(
				20, true));
		tblColumnLayout1.setColumnData(tblclmnHanviet, new ColumnWeightData(15,
				true));
		tblColumnLayout1.setColumnData(tblclmnVietnameseMeaning,
				new ColumnWeightData(35, true));
		composite_2.setLayout(tblColumnLayout1);
		tblvCompoundWords
				.addSelectionChangedListener(new ISelectionChangedListener() {
					private Vocabulary compoundWord = null;

					@Override
					public void selectionChanged(SelectionChangedEvent event) {
						if (event.getSelection().isEmpty()) {
							return;
						}

						if (event.getSelection() instanceof IStructuredSelection) {
							IStructuredSelection selection = (IStructuredSelection) event
									.getSelection();
							compoundWord = (Vocabulary) selection
									.getFirstElement();
							selectedWord = commonServices.getVocabularyDao()
									.getVocabularyWithExamples(
											compoundWord.getVocabularyId());
							initDataBindings();
						}

					}
				});
		CommonUtils.vocabulariesHookDoubleClickCommand(tblvCompoundWords);

		Group grpExample = new Group(composite, SWT.NONE);
		GridData gd_grpExample = new GridData(SWT.FILL, SWT.FILL, true, true,
				1, 1);
		gd_grpExample.widthHint = 459;
		grpExample.setLayoutData(gd_grpExample);
		grpExample.setText("Examples");
		grpExample.setLayout(new GridLayout(1, false));

		Composite composite_3 = new Composite(grpExample, SWT.NONE);
		composite_3.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true,
				1, 1));

		tblvExamples = new TableViewer(composite_3, SWT.BORDER
				| SWT.FULL_SELECTION);
		tblExamples = tblvExamples.getTable();
		tblExamples.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true,
				1, 1));
		tblExamples.setLinesVisible(true);
		tblExamples.setHeaderVisible(true);

		TableViewerColumn tbclvSentence = new TableViewerColumn(tblvExamples,
				SWT.NONE);
		TableColumn tblclmnSentence = tbclvSentence.getColumn();
		tblclmnSentence.setText("Sentence");

		TableViewerColumn tbclExVnMeaning = new TableViewerColumn(tblvExamples,
				SWT.NONE);
		TableColumn tblclmnVietnameseMeaning_1 = tbclExVnMeaning.getColumn();
		tblclmnVietnameseMeaning_1.setText("Vietnamese meaning");

		TableViewerColumn tbclExEnMeaning = new TableViewerColumn(tblvExamples,
				SWT.NONE);
		TableColumn tblclmnEnglishMeaning = tbclExEnMeaning.getColumn();
		tblclmnEnglishMeaning.setText("English meaning");
		TableColumnLayout tblColumnLayout2 = new TableColumnLayout();
		tblColumnLayout2.setColumnData(tblclmnSentence, new ColumnWeightData(
				30, true));
		tblColumnLayout2.setColumnData(tblclmnVietnameseMeaning_1,
				new ColumnWeightData(35, true));
		tblColumnLayout2.setColumnData(tblclmnEnglishMeaning,
				new ColumnWeightData(30, true));
		composite_3.setLayout(tblColumnLayout2);
		CommonUtils.sentencesHookDoubleClickCommand(commonServices,
				tblvExamples);

		initData();
		m_bindingContext = initDataBindings();
	}

	@Override
	public void commit(boolean onSave) {
		super.commit(onSave);
		commonServices.getKanjiDao().merge(kanji);
		tblvCompoundWords.refresh();
	}

	private void createToolBar(final Section section) {
		ToolBar toolbar = new ToolBar(section, SWT.FLAT);
		section.setTextClient(toolbar);

		ToolItem addItem = new ToolItem(toolbar, SWT.PUSH);
		addItem.setImage(Activator.getImageDescriptor("/icons/add.gif")
				.createImage());
		addItem.setToolTipText("Add a related Vocabulary to this Vocabulary");

		addItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				AddRelatedVocabularyDialog relatedVocabularyDialog = new AddRelatedVocabularyDialog(
						section.getShell(), commonServices);
				if (relatedVocabularyDialog.open() == Window.OK) {
					Set<Vocabulary> selectedVocabularies = relatedVocabularyDialog
							.getSelectedVocabularies();
					if (!selectedVocabularies.isEmpty()) {
						// update selected vocabulary as a compound word of
						// current Kanji
						kanji.getCompoundWords().addAll(selectedVocabularies);
						commonServices.getKanjiDao().merge(kanji);

						// update current vocabulary as a related vocabulary of
						// selected vocabulary
//						Vocabulary relatedVocabulary = commonServices
//								.getVocabularyDao().getVocabularyWithKanjis(
//										selectedVocabulary.getVocabularyId());
//						relatedVocabulary.getKanjis().add(kanji);
//						commonServices.getVocabularyDao().update(
//								relatedVocabulary);

						m_bindingContext.updateModels();
						tblvCompoundWords.refresh();
						tblvCompoundWords.setSelection(new StructuredSelection(
								selectedVocabularies.toArray()));
					}
				}
			}
		});

		ToolItem removeItem = new ToolItem(toolbar, SWT.PUSH);
		removeItem.setImage(Activator.getImageDescriptor("/icons/delete.gif")
				.createImage());
		removeItem
				.setToolTipText("Remove selected Category that this vocabulary belong to");

		removeItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection selection = (IStructuredSelection) tblvCompoundWords
						.getSelection();
				Set<Vocabulary> selectedVocabularies = new HashSet<Vocabulary>();
				for (Iterator<Vocabulary> iter = selection.iterator(); iter
						.hasNext();) {
					selectedVocabularies.add(iter.next());
				}
				if (!selectedVocabularies.isEmpty()) {
					boolean confirm = MessageDialog.openConfirm(
							section.getShell(), "Deleting confirmation!",
							"Are you sure you want to delete this Vocabulary?");
					if (confirm) {
						// remove selected vocabulary as a compound word of
						// current Kanji
						kanji.getCompoundWords().removeAll(selectedVocabularies);
						commonServices.getKanjiDao().update(kanji);

						// remove current Kanji of selected vocabulary
//						Vocabulary relatedVocabulary = commonServices
//								.getVocabularyDao().getVocabularyWithKanjis(
//										selectedVocabulary.getVocabularyId());
//						relatedVocabulary.getKanjis().remove(kanji);
//						commonServices.getVocabularyDao().merge(
//								relatedVocabulary);
					}

					m_bindingContext.updateModels();
					tblvCompoundWords.refresh();
				}

			}
		});
	}

	protected DataBindingContext initDataBindings() {
		DataBindingContext bindingContext = new DataBindingContext();
		//
		ObservableSetContentProvider setContentProvider = new ObservableSetContentProvider();
		IObservableMap[] observeMaps = BeansObservables
				.observeMaps(setContentProvider.getKnownElements(),
						Vocabulary.class, new String[] { "vocabulary",
								"furigana", "hanviet", "vnMeaning" });
		tblvCompoundWords.setLabelProvider(new ObservableMapLabelProvider(
				observeMaps));
		tblvCompoundWords.setContentProvider(setContentProvider);
		//
		IObservableSet compoundWordsSet = BeanProperties.set("compoundWords")
				.observe(kanji);
		tblvCompoundWords.setInput(compoundWordsSet);
		//
		ObservableSetContentProvider setContentProvider_2 = new ObservableSetContentProvider();
		IObservableMap[] observeMaps_2 = BeansObservables.observeMaps(
				setContentProvider_2.getKnownElements(), Sentence.class,
				new String[] { "sentence", "vnMeaning", "enMeaning" });
		tblvExamples.setLabelProvider(new ObservableMapLabelProvider(
				observeMaps_2));
		tblvExamples.setContentProvider(setContentProvider_2);
		//
		IObservableSet vocabularyExamplesSelectedWordObserveSet = BeanProperties
				.set("vocabularyExamples").observe(selectedWord);
		tblvExamples.setInput(vocabularyExamplesSelectedWordObserveSet);

		return bindingContext;
	}
}
